#include "includes/phrase.h"
#include <QTextStream>
#include <QFile>
#include <QDomDocument>
#include <QString>
#include <iostream>
#include <exception>

//simple constructor to initialize all fields
Phrase::Phrase()
{
    name = QString();
    cartoonFilename = QString();
    videoFilename = QString();
    iconFilename = QString();
    difficulty = 1;
    sequence = 2;
    synonyms = QStringList();
}

//constructor for a named Phrase
Phrase::Phrase(const QString& n)
{
    Phrase();
    name = QString(n);
}

// parameterised constructor: name and icon filename
Phrase::Phrase(const QString& name, const QString& iconFilename) {
	setName(name);
	setIconFilename(iconFilename);
}

//copy constructor
Phrase::Phrase(const Phrase& old)
{
    name = QString(old.getName());
    cartoonFilename = QString(old.getCartoonFilename());
    videoFilename = QString(old.getVideoFilename());
    iconFilename = QString(old.getIconFilename());
    difficulty = old.getDifficulty();
    sequence = old.getSequence();
    synonyms = QStringList(old.getSynonyms());
    lesson = old.getLesson();
}

//Takes a QDomNode as input and places this Phrase as it's last child.
void Phrase::saveToChild(QDomNode& parent) const
{
    QDomDocument doc = parent.ownerDocument();
    QDomElement phrase = doc.createElement("phrase");

    if (parent.isNull()) parent = phrase;
    else parent.appendChild(phrase);

    phrase.setAttribute("sequence", sequence);
    phrase.setAttribute("level", difficulty);

    QDomElement content = doc.createElement("content");
    phrase.appendChild(content);
    content.appendChild(doc.createTextNode(name));

    QDomElement car = doc.createElement("cartoon");
    phrase.appendChild(car);
    car.appendChild(doc.createTextNode(cartoonFilename));

    QDomElement vid = doc.createElement("video");
    phrase.appendChild(vid);
    vid.appendChild(doc.createTextNode(videoFilename));

    QDomElement ico = doc.createElement("icon");
    phrase.appendChild(ico);
    ico.appendChild(doc.createTextNode(iconFilename));

    QDomElement syn = doc.createElement("synonyms");
    phrase.appendChild(syn);
    syn.appendChild(doc.createTextNode(synonyms.join(", ")));
}


//easy to use: you can pass it a document and it'll find the first child phrase
//or you can pass in the phrase node directly and both will initialize this
//Phrase object correctly
Phrase& Phrase::loadFromNode(QDomNode inputNode)
{
    QDomElement root;
    if (inputNode.isDocument())
    {
        root = inputNode.firstChildElement("phrase");
        if (root.isNull()) return *this;
    } else if (inputNode.isElement())
    {
        if (inputNode.toElement().tagName() == "phrase")
            root = inputNode.toElement();
        else return *this;
    } else return *this;

    sequence = root.attribute("sequence", "2").toInt();
    difficulty = root.attribute("level" , "1").toInt();

    if (root.elementsByTagName("content").at(0).firstChild().isText())
        name = root.elementsByTagName("content").at(0).firstChild().toText().nodeValue();

    if (root.elementsByTagName("cartoon").at(0).firstChild().isText())
        cartoonFilename = root.elementsByTagName("cartoon").at(0).firstChild().toText().nodeValue();

    if (root.elementsByTagName("video").at(0).firstChild().isText())
        videoFilename = root.elementsByTagName("video").at(0).firstChild().toText().nodeValue();

    if (root.elementsByTagName("icon").at(0).firstChild().isText())
        iconFilename = root.elementsByTagName("icon").at(0).firstChild().toText().nodeValue();

    if (root.elementsByTagName("synonyms").at(0).firstChild().isText())
        synonyms = root.elementsByTagName("synonyms").at(0).firstChild().toText().nodeValue().split(", ");

    return *this;
}


//Many simple GETters and SETters.
void Phrase::setName(QString n)
{ name = n; }

QString Phrase::getName() const
{ return name;}

//////////////////////////////////////////////////////
void Phrase::setCartoonFilename(QString fname)
{ cartoonFilename = fname; }

QString Phrase::getCartoonFilename() const
{ return cartoonFilename; }

//////////////////////////////////////////////////////
void Phrase::setVideoFilename(QString fname)
{ videoFilename = fname; }

QString Phrase::getVideoFilename() const
{ return videoFilename; }

///////////////////////////////////////////////////////
void Phrase::setDifficulty(int n)
{ if (n > 0 && n < 4)
    difficulty = n;
}

int Phrase::getDifficulty() const
{ return difficulty; }

////////////////////////////////////////////////////////
void Phrase::setSequence(int n)
{ if (n < 5 && n > 0) sequence = n; }

int Phrase::getSequence() const
{ return sequence; }

////////////////////////////////////////////////////////
void Phrase::setSynonyms(QStringList newList)
{ synonyms = newList; }

QStringList Phrase::getSynonyms() const
{ return synonyms; }

/////////////////////////////////////////////////////////
void Phrase::setIconFilename(QString fname)
{ iconFilename = fname; }

QString Phrase::getIconFilename() const
{ return iconFilename; }

/*
 * Lesson name
 */
void Phrase::setLesson(const QString lessonName) {
    lesson = lessonName;
}
QString Phrase::getLesson() const {
    return lesson;
}

// remove synonyms from memory. this is used once
// the thesaurus hash table has been loaded with synonyms and
// corresponding phrases. we don't need them in memory here
// any more
void Phrase::purgeSynonyms() {
        synonyms.clear();
}

// equality operator
bool Phrase::operator== (const Phrase& other) const {
	// QString allows == for comparing strings.
	// equal names is only criteria
	return getName() == other.getName();
}

bool Phrase::operator== (const QString& other) const {
    return getName() == other;
}

bool Phrase::operator< (const Phrase& other) const {
    return (getName() < other.getName());
}
